﻿

#include "framework.h"
#include "CreateWindow.h"
#include "../MyMath/CommonD3d.h"
#include "../MyMath/Vec3.h"
#include "../MyMath/Vec4.h"

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    CreateWindowApp app(hInstance);
    app.Init();
    return app.Run();
}

struct Vertex
{
    Vec3 pos;
    Vec4 color;
};


//============================================
// 
CreateWindowApp::CreateWindowApp(HINSTANCE hInstance):BaseApp(hInstance)
{
    m_bgColor[0] = 0;
    m_bgColor[1] = 0;
    m_bgColor[2] = 0;
    m_bgColor[3] = 1;
}

CreateWindowApp::~CreateWindowApp()
{
    SAFE_RELEASE(m_pVertexLayout);
    SAFE_RELEASE(m_pVertexBuffer);
    SAFE_RELEASE(m_pVertexShader);
    SAFE_RELEASE(m_pPixelShader);
}

void CreateWindowApp::Init()
{
    BaseApp::Init();
    
    // init shader
    // 创建顶点着色器
    const D3D11_INPUT_ELEMENT_DESC inputLayout[2] = {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    };

    ID3DBlob* blobVs = nullptr;
    HR(Shader::CreateShaderFromFile(L"triangle_vs.hlsl", "main", "vs_5_0", &blobVs));
    HR(m_pDevice->CreateVertexShader(blobVs->GetBufferPointer(), blobVs->GetBufferSize(), nullptr, &m_pVertexShader));

    // 创建并绑定顶点布局
    HR(m_pDevice->CreateInputLayout(inputLayout, ARRAYSIZE(inputLayout),
        blobVs->GetBufferPointer(), blobVs->GetBufferSize(), &m_pVertexLayout));
    SAFE_RELEASE(blobVs);

    // 创建像素着色器
    ID3DBlob* blobPs = nullptr;
    HR(Shader::CreateShaderFromFile(L"triangle_ps.hlsl", "main", "ps_5_0", &blobPs));
    HR(m_pDevice->CreatePixelShader(blobPs->GetBufferPointer(), blobPs->GetBufferSize(), nullptr,&m_pPixelShader));
    SAFE_RELEASE(blobPs);

    // init vertices
    // 设置三角形顶点
    Vertex vertices[] = {
        { Vec3(0.0f, 0.5f, 0.5f), Vec4(0.0f, 1.0f, 0.0f, 1.0f) },
        { Vec3(0.5f, -0.5f, 0.5f), Vec4(0.0f, 0.0f, 1.0f, 1.0f) },
        { Vec3(-0.5f, -0.5f, 0.5f), Vec4(1.0f, 0.0f, 0.0f, 1.0f) }
    };

    // 设置顶点缓冲区描述
    D3D11_BUFFER_DESC vbd;
    ZeroMemory(&vbd, sizeof(vbd));
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof vertices;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;

    // 新建顶点缓冲区
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory(&InitData, sizeof(InitData));
    InitData.pSysMem = vertices;
    HR(m_pDevice->CreateBuffer(&vbd, &InitData, &m_pVertexBuffer));


    // ******************
    // 给渲染管线各个阶段绑定好所需资源
    // 输入装配阶段的顶点缓冲区设置
    UINT stride = sizeof(Vertex);	// 跨越字节数
    UINT offset = 0;						// 起始偏移量

    m_pDeviceContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);

    // 设置图元类型，设定输入布局
    m_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    m_pDeviceContext->IASetInputLayout(m_pVertexLayout);

    // 将着色器绑定到渲染管线
    m_pDeviceContext->VSSetShader(m_pVertexShader, nullptr, 0);
    m_pDeviceContext->PSSetShader(m_pPixelShader, nullptr, 0);

    //// ******************
    //// 设置调试对象名
    ////
    //D3D11SetDebugObjectName(m_pVertexLayout.Get(), "VertexPosColorLayout");
    //D3D11SetDebugObjectName(m_pVertexBuffer.Get(), "VertexBuffer");
    //D3D11SetDebugObjectName(m_pVertexShader.Get(), "Trangle_VS");
    //D3D11SetDebugObjectName(m_pPixelShader.Get(), "Trangle_PS");
}

void CreateWindowApp::UpdateScene(float dt)
{
}

void CreateWindowApp::DrawScene()
{
    // MyLog::Info("CreateWindowApp::DrawScene Called!\n");

    assert(m_pDeviceContext);
    assert(m_pDevice);
    assert(m_pSwapChain);

    m_pDeviceContext->ClearRenderTargetView(m_pRenderTargetView, m_bgColor);
    m_pDeviceContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

    // 绘制三角形
    m_pDeviceContext->Draw(3, 0);

    HR(m_pSwapChain->Present(NULL, NULL));
}
